#ifndef _CSEOBJ_H_CSEAPI_
#define _CSEOBJ_H_CSEAPI_

// const of CSE type format specification
#define CSE_INT                    _T("i")
#define CSE_WINT                   _T("w")
#define CSE_FLOAT                  _T("f")
#define CSE_STR                    _T("s")
#define CSE_NSTR                   _T("S")
#define CSE_TIER                   _T("()")
#define CSE_BUFF                   _T("[]")
#define CSE_DICT                   _T("{}")
#define CSE_INSTANCE               _T("<>")
#define CSE_ID                     _T("%#")
#define CSE_NOTATOR                _T("%@")
#define CSE_STRONG                 _T("%+")
#define CSE_WEAK                   _T("%-")

class CSE_IMPEXP_IN TCseObj
{
private:
    TCseObj(TInt disable);          // disable construct by TInt
    TCseObj(TWint disable);         // disable construct by TWint
    TCseObj(TDouble disable);       // disable construct by TDouble
    TCseObj(const TXchar *disable); // disable construct by TXchar*

//    TBool operator==(CseObj obj) const;  // check confusion convertion
//    TBool operator!=(CseObj obj) const;  // check confusion convertion
//    TBool operator>(CseObj obj) const;   // check confusion convertion
//    TBool operator>=(CseObj obj) const;  // check confusion convertion
//    TBool operator<(CseObj obj) const;   // check confusion convertion
//    TBool operator<=(CseObj obj) const;  // check confusion convertion

protected:
    CseObj m_data;
    
    // if inherited class disable "=", uses this API
    TCseObj& assign(CseObj obj);

public:
    TCseObj();
    TCseObj(CseObj obj);
    TCseObj(const TCseObj& obj);
    ~TCseObj();
    
    static TCseObj format(const TXchar *frmt, ...);

    // create by copy
    TCseObj(const TIntObj& iObj);
    TCseObj(const TWintObj& wObj);
    TCseObj(const TFloatObj& fObj);
    TCseObj(const TCharArray& s);
    TCseObj(const TIntArray& t);
    TCseObj(const TObjArray& b);
    TCseObj(const TEntryArray& d);
    
    // create by cut
    TCseObj(int MagicNum, TCharArray& s);
    TCseObj(int MagicNum, TIntArray& t);
    TCseObj(int MagicNum, TObjArray& b);
    TCseObj(int MagicNum, TEntryArray& d);

    // object assign
    TCseObj& operator=(const TCseObj& obj);
    TCseObj& operator=(CseObj obj);

    TBool operator==(TCseObj& obj) const;
    TBool operator!=(TCseObj& obj) const;
    TBool operator>(TCseObj& obj) const;
    TBool operator>=(TCseObj& obj) const;
    TBool operator<(TCseObj& obj) const;
    TBool operator<=(TCseObj& obj) const;

    operator CseObj() const;
    CseObj operator->() const;

    TIntObj& iObj() const;
    TWintObj& wObj() const;
    TFloatObj& fObj() const;
    TCharArray& sArray() const;
    TIntArray& tArray() const;
    TObjArray& bArray() const;
    TEntryArray& dArray() const;

    // str/tier/buff/dict
    int len() const;
    void clear() const;
    TBool fixSize(int iRsvd) const;
    void join(const TCseObj& obj, int index=0) const;

    // common API for str, tier, buff
    TCseObj slice(int index, int len) const;
    const TCseObj& append(const TCseObj& obj, int *pIndex=NULL) const;
    const TCseObj& insert(int index, const TCseObj& obj) const;
    void remove(int index, int len=1) const;
    void truncate(int iLen) const;
    void sort() const;

    // All CSE type
    int type() const;
    TCharArray str() const;
    TCharArray beStr() const;
    TUint32 hash() const;
    int compare(CseObj other) const; // 0: same, >0: large, <0: less

    CseObj transfer(const TCseObj& value);
    TBool isMapped() const;
    TBool isLinked() const;

    TInt32 getFlag() const;
    void setFlag(TInt32 flag) const;
    TBool optionOn(int iBit) const;
    void setOption(int iBit) const;
    void clearOption(int iBit) const;

    // API for str
    TCseObj toId() const;

    // API for buff
    TCseObj& operator[](int index) const;
    TCseObj& sub(int index) const;
    TCseObj pop(int index=-1) const;
    void push(const TCseObj& obj) const;
    TCseObj toNotator(int index=0) const;

    // API for dict
    TBool isSpace() const;
    TCseObj get(const TCseObj& key) const;
    const TCseObj& set(const TCseObj& key, const TCseObj& value) const;
    TCseObj quickGet(const TCseObj& key) const;
    TBool quickSet(const TCseObj& key, const TCseObj& value) const;
    TCseObj getEx(const TCseObj& key, const TCseObj& vDefault) const;
    TCseObj setEx(const TCseObj& key, const TCseObj& value) const;
    TBool enumItem(PEntryPoint& pEntry, TCseObj *pKey=NULL, TCseObj *pValue=NULL) const;

    // API for strong
    TCseObj strongGet() const;
    const TCseObj& strongSet(const TCseObj& value) const;
};

extern CSE_IMPEXP_IN TCseObj CSE_HOLD(CseObj obj);
extern CSE_IMPEXP_IN int CsePrint(int ArgNum, ...);

#endif
